package com.contract.management.service;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.transaction.Transactional;

import org.apache.poi.xwpf.usermodel.BreakType;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFonts;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.contract.management.bean.ExtraData;
import com.contract.management.domain.CommJpaRepository;
import com.contract.management.domain.ContSmallClass;
import com.contract.management.domain.Contract;
import com.contract.management.domain.NoSeq;
import com.contract.management.domain.SbItems;
import com.contract.management.domain.User;
import com.contract.management.domain.WorkflowLog;
import com.contract.management.domain.WorkflowNode;
import com.contract.management.util.StrUtils;
import com.contract.management.util.WorkFlowUtils;

@Service
public class ContractService {
	
	@Value("${office.basepath}")
	private String basePath;
	
	@Autowired
	private CommJpaRepository repo;

	private SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
	
	/**
	 * 设置合同费用合计和正常价格
	 * @param ct
	 * @return
	 */
	public void setContractMoney(Contract ct) {		
		if(ct.getSbItems() != null && ct.getSbItems().size() > 0) {
			int fyhj = 0;
			int zcbj = 0;
			for(SbItems sb : ct.getSbItems()) {
				fyhj += sb.getFy();
				zcbj += sb.getZcbj();
			}
			//专利加上代交官费服务费
			if("PR".equals(ct.getYwlx())) {
				fyhj += ct.getData().getM4();
				zcbj += ct.getData().getM4();
			}
			ct.setFyhj(fyhj);
			ct.setZcjg(zcbj);
		}
	}
	
	/**
	 * 获取合同模板录入ID
	 * @param ct
	 * @return
	 */
	public String getTemplateId(Contract ct) {
		//双软
		if("DS".equals(ct.getYwlx())) {
			return "#" + ct.getYwlx().toLowerCase() + "_" +  ct.getArea().toLowerCase() + "_template";
		} else {
			return "#" + ct.getYwlx().toLowerCase() + "_template";	
		}
			
	}
	
	/**
	 * 保存并生成空白合同
	 * @param ct
	 * @return
	 */
	@Transactional
	public void insertBlankContract(Contract ct) {
		String conNo = createContractNo(ct);
		ct.setType(2);
		ct.setCreateTime(new Date());
		ct.setNo(conNo);
		
		ct.setData(new ExtraData());
		
		ct.setCurNode(repo.queryOne("from WorkflowNode where id = ?0", 1));
		ct.setNextOper("打印合同");
		String nodeInfo = "空白合同创建完成";
		ct.setNodeInfo(nodeInfo);
		
		//生成电子合同
		String filename = createContract(ct);
		ct.setDocName(filename);
		
		repo.persist(ct);
		
		WorkflowLog log = new WorkflowLog();
		log.setCt(ct);
		log.setUser(ct.getUser());
		log.setSpjg(1);
		log.setSpsm("创建空白合同");
		log.setCreateTime(new Date());
		repo.persist(log);
	}
	
	/**
	 * 保存合同并生成电子合同
	 * @param ct
	 * @return 合同状态信息
	 */
	@Transactional
	public WorkflowNode insertContract(Contract ct) {
		String conNo = createContractNo(ct);
		ct.setCreateTime(new Date());
		ct.setType(1);
		ct.setNo(conNo);
		
		setContractMoney(ct);
		ct.setCurNode(repo.queryOne("from WorkflowNode where id = ?0", 1));
		WorkflowNode nextNode = WorkFlowUtils.getNextNode(ct, repo);
		ct.setNextOper(nextNode.getName());
		ct.setNodeInfo("电子合同创建完成");
		
		//生成电子合同
		String filename = createContract(ct);
		ct.setDocName(filename);
		repo.persist(ct);
		String ywlx = ct.getYwlx();
		//商标合同                               //版权
		if(ct.getSbItems() != null && ct.getSbItems().size() > 0) {
			for(SbItems sb : ct.getSbItems()) {
				if(sb != null) {
					sb.setCt(ct);
					repo.persist(sb);
				}
			}
		}
		WorkflowLog log = new WorkflowLog();
		log.setCt(ct);
		log.setUser(ct.getUser());
		log.setSpjg(1);
		log.setSpsm("创建电子合同");
		log.setMemo(nextNode.getDesc());
		log.setCreateTime(new Date());
		repo.persist(log);
		
		return nextNode;
	}
	
	/**
	 * 更新合同并生成电子合同
	 * @param ct
	 * @return
	 */
	@Transactional
	public WorkflowNode updateContract(Contract ct) {
		//生成电子合同
		setContractMoney(ct);
		String filename = createContract(ct);
		ct.setDocName(filename);
		
		WorkflowNode nextNode = WorkFlowUtils.getNextNode(ct, repo);
		ct.setNextOper(nextNode.getName());
		ct.setNodeInfo("合同修改完成，下一步" + nextNode.getName());
		
		repo.merge(ct);
		
		//带子项合同
		if(ct.getSbItems() != null && ct.getSbItems().size() > 0) {
			repo.queryUpdate("delete from SbItems where ct.id = ?0", ct.getId());
			for(SbItems sb : ct.getSbItems()) {
				if(sb != null) {
					sb.setCt(ct);
					repo.persist(sb);
				}
			}
		}
		
		WorkflowLog log = new WorkflowLog();
		log.setCt(ct);
		log.setUser(ct.getUser());
		log.setSpjg(1);
		log.setSpsm("修改合同完成");
		log.setMemo(nextNode.getDesc());
		log.setCreateTime(ct.getCreateTime());
		repo.persist(log);
		return nextNode;
	}
	
	/**
	 * 更新空白合同
	 * @param ct
	 */
	@Transactional
	public void updateBlankContract(Contract ct) {
		//生成电子合同
		setContractMoney(ct);
		String filename = createContract(ct);
		ct.setDocName(filename);
		repo.merge(ct);
		
		//商标合同
		if(ct.getSbItems() != null && ct.getSbItems().size() > 0) {
			repo.queryUpdate("delete from SbItems where ct.id = ?0", ct.getId());
			for(SbItems sb : ct.getSbItems()) {
				if(sb != null) {
					sb.setCt(ct);
					repo.persist(sb);
				}
			}
		}
	}

	/**
	 * 获取合同列表
	 * @param user		审核人
	 * @param curNodeId	当前节点ID
	 * @return
	 */
	public List<Map<String, Object>> getContList1(String no, String jfWtr, String username, User user, User audit, int... curNodeId) {
		List<Integer> list = new ArrayList<>();
		for (int id : curNodeId) {
			list.add(id);
		}
		List<Object[]> ret = null;
		Map<String, Object> params = new HashMap<>();
		String sql= "select c.id, c.no, c.area, c.company.name, c.contSmallClass.name, c.ycfq, c.isHjb, c.jfWtr, c.jfLxr, c.fyhj, c.nodeInfo, c.user.name, c.createTime, c.nextOper, c.curNode.id, c.type, c.auditMemo from Contract c where ";
		if(user != null) {
			sql += "c.user = :user and c.curNode.id in (:curNode)";
			params.put("user", user);
			params.put("curNode", list);
			
		} else if(audit != null) {
			sql += "c.audit = :user and c.curNode.id in (:curNode)";
			params.put("user", audit);
			params.put("curNode", list);
		}
		if(!StrUtils.isEmpty(no)) {
			sql += " and c.no like :no";
			params.put("no", "%" + no + "%");
		}
		if(!StrUtils.isEmpty(jfWtr)) {
			sql += " and c.jfWtr like :jfWtr";
			params.put("jfWtr", "%" + jfWtr + "%");
		}
		if(!StrUtils.isEmpty(username)) {
			sql += " and c.user.name like :username";
			params.put("username", "%" + username + "%");
		}
		ret = repo.query(sql, params);
		List<Map<String, Object>> data = new ArrayList<>();
		for (Object[] objs : ret) {
			Map<String, Object> map = new HashMap<>();
			map.put("id", objs[0]);
			map.put("no", objs[1]);
			map.put("area", objs[2]);
			map.put("company", objs[3]);
			map.put("ywmc", objs[4]);
			map.put("ycfq", objs[5]);
			map.put("isHjb", objs[6]);
			map.put("jfWtr", objs[7]);
			map.put("jfLxr", objs[8]);
			map.put("fyhj", objs[9]);
			map.put("nodeInfo", objs[10]);
			map.put("username", objs[11]);
			map.put("createTime", objs[12]);
			map.put("nextOper", objs[13]);
			map.put("curNodeId", objs[14]);
			map.put("type", objs[15]);
			map.put("auditMemo", objs[16]);
			data.add(map);
		}
		return data;
	}
	
	public List<Map<String, Object>> getContList(User user, User audit, int... curNodeId) {
		List<Integer> list = new ArrayList<>();
		for (int id : curNodeId) {
			list.add(id);
		}
		List<Object[]> ret = null;
		Map<String, Object> params = new HashMap<>();
		String sql= "select c.id, c.no, c.area, c.company.name, c.contSmallClass.name, c.ycfq, c.isHjb, c.jfWtr, c.jfLxr, c.fyhj, c.nodeInfo, c.user.name, c.createTime, c.nextOper, c.curNode.id, c.type, c.auditMemo from Contract c where ";
		if(user != null) {
			sql += "c.user = :user and c.curNode.id in (:curNode)";
			params.put("user", user);
			params.put("curNode", list);
			
		} else if(audit != null) {
			sql += "c.audit = :user and c.curNode.id in (:curNode)";
			params.put("user", audit);
			params.put("curNode", list);
		}
		
		ret = repo.query(sql, params);
		List<Map<String, Object>> data = new ArrayList<>();
		for (Object[] objs : ret) {
			Map<String, Object> map = new HashMap<>();
			map.put("id", objs[0]);
			map.put("no", objs[1]);
			map.put("area", objs[2]);
			map.put("company", objs[3]);
			map.put("ywmc", objs[4]);
			map.put("ycfq", objs[5]);
			map.put("isHjb", objs[6]);
			map.put("jfWtr", objs[7]);
			map.put("jfLxr", objs[8]);
			map.put("fyhj", objs[9]);
			map.put("nodeInfo", objs[10]);
			map.put("username", objs[11]);
			map.put("createTime", objs[12]);
			map.put("nextOper", objs[13]);
			map.put("curNodeId", objs[14]);
			map.put("type", objs[15]);
			map.put("auditMemo", objs[16]);
			data.add(map);
		}
		return data;
	}
	
	/**
	 * 生成合同编号
	 * @param ct
	 * @return
	 */
	private synchronized String createContractNo(Contract ct) {
		StringBuilder sb = new StringBuilder(ct.getCompany().getCode());
		sb.append(ct.getArea());
		sb.append(ct.getYwlx());
		if(ct.getYcfq() == null) {
			sb.append("O");
		} else {
			sb.append(ct.getYcfq());
		}
		
		Calendar now = Calendar.getInstance();
		sb.append(df.format(now.getTime()));
		int day = now.get(Calendar.DAY_OF_MONTH);
		NoSeq seq = repo.queryOne("from NoSeq");
		int sort = 1;
		if(day == seq.getDay()) {
			sort = seq.getSeq();
			seq.setSeq(++sort); 
		} else {
			seq.setSeq(sort);
			seq.setDay(day);
		}
		repo.merge(seq);
		sb.append(String.format("%03d", sort));
		if(ct.getIsHjb()) {
			sb.append("E");
		}
		return sb.toString();
	}
	
	/**
	 * 获取表单模板文件名称
	 * @param ct
	 * @return
	 */
	private String getTemplateName(Contract ct) {
		ContSmallClass smallClass = ct.getContSmallClass();
		StringBuilder sb = new StringBuilder();
		sb.append(ct.getArea());
		sb.append("_");
		sb.append(smallClass.getTempNo());
		
		if(smallClass.getHasHjb() == 1 && ct.getIsHjb()) {
			sb.append("_H");
		} else if( smallClass.getDefaultHjb() == 1) {
			sb.append("_H");
		}
		
		if(smallClass.getId() == 22 || smallClass.getId() == 45) {
			sb.append("_").append("B");
		} else if(smallClass.getId() == 23 || smallClass.getId() == 46) {
			sb.append("_").append("S");
		}
		
		sb.append("_").append(ct.getYcfq());
		
		return sb.toString() + ".docx";
		
		/*
		String tempName = "";
		switch (ct.getYwlx()) {
		case "AD":	//加计扣除
		case "AS":	//专审
		case "AY":	//年审
		case "CA":	//保密
		case "LC":	//长期合作协议
		case "TD":	//商标
			tempName = ct.getArea().getCode() + "_" + ct.getYwlx();
			break;
		case "CR":	//版权
		case "TM":	//中小
			tempName = ct.getArea().getCode() + "_" + ct.getYwlx() + "_" + ct.getYcfq();
			break;
		case "HA":	//高转
		case "HC":	//高培
		case "HE":	//高企
		case "HP":	//高品
		case "IA":	//无形资产评估
		case "OA":	//拨款类项目
		case "OQ":	//资质认定类项目
		case "PT":	//民营
		case "SA":	//姑苏天使
		case "TG":	//小巨人
			tempName = ct.getArea().getCode() + "_" + ct.getYwlx() + "_" + ct.getYcfq().getCode();
			break;
		case "TR":	//商标
		case "IS":	//贯标
			tempName = ct.getArea().getCode() + "_" + ct.getYwlx() + (ct.getIsHjb() ? "_H_" : "_") + ct.getYcfq();
			break;
		default:
			break;
		}
		tempName = tempName + ".docx";
		return tempName;
		*/
	}
	/**
	 * 创建电子合同
	 * @param ct
	 * @return 电子合同文件名
	 */
	private String createContract(Contract ct) throws RuntimeException {
		SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmssSSS");
		SimpleDateFormat wkDf = new SimpleDateFormat("yyyy-MM-dd");
		String tempName = getTemplateName(ct);
		String tempPath = basePath + "templates/"  + tempName;
		if(!new File(tempPath).exists()) {
			throw new RuntimeException("该合同模板不存在");
		}
		String filename = df.format(new Date()) + ".docx";
		String filePath = basePath +  "contracts/" + filename;

		try( InputStream is = new FileInputStream(new File(tempPath));
				OutputStream os = new FileOutputStream(new File(filePath)); 
				XWPFDocument doc = new XWPFDocument(is)) {
			
			Iterator<XWPFParagraph> itPara = doc.getParagraphsIterator();
			boolean placeholder = false;
			String txt = "";
            while (itPara.hasNext()) {
                XWPFParagraph paragraph = (XWPFParagraph) itPara.next();
                List<XWPFRun> runs = paragraph.getRuns();
                for(XWPFRun run : runs) {
                	String rt = run.getText(0);
                	if(rt == null) continue;
                	//${xxxx} 可能在多个run中，这里进行合并
                	if(rt.trim().startsWith("${")) {
                		placeholder = true;
                		txt = rt.trim();
                		run.setText("", 0);
                	} else if(placeholder == true) {
                		txt += rt.trim();
                		run.setText("", 0);
                	}
                	if(placeholder == true && rt.trim().endsWith("}")) {
                		placeholder = false;
                	} else {
                		continue;
                	}      	
                	if("${no}".equals(txt)) {
                		run.setText(ct.getNo(), 0);
                	//甲方信息
                	} else if("${jfWtr}".equals(txt)) {
                    	run.setText(StrUtils.addBlank(ct.getJfWtr(), 78), 0);
                	} else if("${jfTxdz}".equals(txt)) {
                		run.setText(StrUtils.addBlank(ct.getJfTxdz(), 83), 0);
                	} else if("${jfLxr}".equals(txt)) {
                		run.setText(StrUtils.addBlank(ct.getJfLxr(), 33), 0);
                	} else if("${jfWz}".equals(txt)) {
                		run.setText(StrUtils.addBlank(ct.getJfWz(), 34), 0);
                	} else if("${jfDhhm}".equals(txt)) {
                		run.setText(StrUtils.addBlank(ct.getJfDhhm(), 34), 0);
                	} else if("${jfYddh}".equals(txt)) {
                		run.setText(StrUtils.addBlank(ct.getJfYddh(), 35), 0);
                	} else if("${jfDzyj}".equals(txt)) {
                		run.setText(StrUtils.addBlank(ct.getJfDzyj(), 83), 0);
                	//乙方信息
                	} else if("${yfWtr}".equals(txt)) {
                    	run.setText(StrUtils.addBlank(ct.getYfWtr(), 78), 0);
                	} else if("${yfTxdz}".equals(txt)) {
                		run.setText(StrUtils.addBlank(ct.getYfTxdz(), 80), 0);
                	} else if("${yfLxr}".equals(txt)) {
                		run.setText(StrUtils.addBlank(ct.getYfLxr(), 33), 0);
                	} else if("${yfWz}".equals(txt)) {
                		run.setText(StrUtils.addBlank(ct.getYfWz(), 33), 0);
                	} else if("${yfDhhm}".equals(txt)) {
                		run.setText(StrUtils.addBlank(ct.getYfDhhm(), 34), 0);
                	} else if("${yfCzhm}".equals(txt)) {
                		run.setText(StrUtils.addBlank(ct.getYfCzhm(), 34), 0);
                	} else if("${yfDzyj}".equals(txt)) {
                		run.setText(StrUtils.addBlank(ct.getYfDzyj(), 83), 0);
                	//付款方式（1转账、2支票、3现金、4支付宝）
                	} else if("${fk_zz}".equals(txt)) {
                		run.setText(ct.getFkfs() == 1 ? "■" : "□", 0);
                	} else if("${fk_zp}".equals(txt)) {
                		run.setText(ct.getFkfs() == 2 ? "■" : "□", 0);
                	} else if("${fk_xj}".equals(txt)) {
                		run.setText(ct.getFkfs() == 3 ? "■" : "□", 0);
                	} else if("${fk_zfb}".equals(txt)) {
                		run.setText(ct.getFkfs() == 4 ? "■" : "□", 0);
                	//服务费用
                	} else if("${fyhj}".equals(txt)) {
                		run.setText(StrUtils.addRBlank(ct.getFyhj() == 0 ? "" : String.valueOf(ct.getFyhj()), 12), 0);
                	} else if("${fyhj.dx}".equals(txt)) {
                		if(ct.getFyhj() == 0) {
                			run.setText("      ", 0);
                		} else {
                			run.setText(StrUtils.toRmbDx(ct.getFyhj()), 0);
                		}
                		
                	//金额大写 ${jedx[5]}  拾 ${jedx[4]}  万 ${jedx[3]}  仟  ${jedx[2]}  佰  ${jedx[1]}   拾  ${jedx[0]} 元整
                	} else if(txt.startsWith("${jedx[")) {
                		int num = Integer.valueOf(txt.substring(7, 8));
                		List<String> fyhjList = StrUtils.toUpperMoneyList(ct.getFyhj()); 
                		if(num >= fyhjList.size()) {
                			if(ct.getFyhj() == 0) {
                				run.setText("  ", 0);
                			} else {
                				run.setText("零", 0);
                			}
                		} else {
                			if(ct.getFyhj() == 0) {
                				run.setText("  ", 0);
                			} else {
                				run.setText(fyhjList.get(num), 0);
                			}
                		}
                	//退款情形发生时，甲方可要求乙方退款账户
                	} else if("${tkzh}".equals(txt)) {
                		run.setText(StrUtils.addRBlank(ct.getTkzh(), 10), 0);
                	//分期：预付款
                	} else if("${firstPay}".equals(txt)) {
                		run.setText(StrUtils.addRBlank(ct.getFirstPay(), 10), 0);
                	} else if("${firstPay.dx}".equals(txt)) {
                		run.setText(StrUtils.toRmbDx(ct.getFirstPay()), 0);
                	//分期：尾款
                	} else if("${lastPay}".equals(txt)) {
                		run.setText(StrUtils.addRBlank(ct.getFyhj() - (ct.getFirstPay() == null ? 0 : ct.getFirstPay()), 10), 0);
                	//分期：尾款支付时间
                	} else if("${lastPayDate}".equals(txt)) {
                		run.setText(StrUtils.addRBlank(ct.getLastPayDate() == null ? "" : ct.getLastPayDate(), 10), 0);
                	//乙方公司账户
                	} else if("${account}".equals(txt)) {
                		run.setText(ct.getAccount(), 0);
                	//开户银行
                	} else if("${bank}".equals(txt)) {
                		run.setText(ct.getBank(), 0);
                	//银行账号
                	} else if("${bankNumber}".equals(txt)) {
                		run.setText(ct.getBankNumber(), 0);
                	/*** 附加信息 S *****************************************************************/
                	} else if("${data.adYear}".equals(txt)) {
                		run.setText(StrUtils.addRBlank(ct.getData().getAdYear(), 10), 0);
                	} else if("${data.ayYear}".equals(txt)) {
                		run.setText(StrUtils.addRBlank(ct.getData().getAyYear(), 10), 0);
                	} else if("${data.adSum}".equals(txt)) {
                		run.setText(StrUtils.addBlank(ct.getData().getAdSum(), 10), 0);
                	} else if("${data.zxsj}".equals(txt)) {
                		run.setText(StrUtils.addBlank(ct.getData().getZxsj(), 10), 0);
                	} else if("${data.xm}".equals(txt)) {
                		run.setText(StrUtils.addRBlank(ct.getData().getXm(), 20), 0);
                	} else if("${data.percent}".equals(txt)) {
                		run.setText(StrUtils.addRBlank(ct.getData().getPercent(), 5), 0);
                	} else if("${data.p1}".equals(txt)) {
                		if("LC".equals(ct.getYwlx()) && ct.getData().getP1() != null) {
                			String[] strs = ct.getData().getP1().split("\r\n");
                			for(int i = 0; i < strs.length; i++) {
                				if(i == 0) {
                					run.setText(strs[i], 0);
                				} else {
                					run.addCarriageReturn();
                					run.setText(strs[i]);
                				}	
                			}
                		} else {
                			run.setText(StrUtils.addBlank(ct.getData().getP1(), 6), 0);
                		}
                	} else if("${data.p2}".equals(txt)) {
                		if("LC".equals(ct.getYwlx()) && ct.getData().getP2() != null) {
                			String[] strs = ct.getData().getP2().split("\r\n");
                			for(int i = 0; i < strs.length; i++) {
                				if(i == 0) {
                					run.setText(strs[i], 0);
                				} else {
                					run.addCarriageReturn();
                					run.setText(strs[i]);
                				}	
                			}
                		} else {
                			run.setText(StrUtils.addBlank(ct.getData().getP2(), 6), 0);
                		}
                	} else if("${data.p3}".equals(txt)) {
                		run.setText(StrUtils.addBlank(ct.getData().getP3(), 6), 0);
                	} else if("${data.p4}".equals(txt)) {
                		run.setText(StrUtils.addBlank(ct.getData().getP4(), 6), 0);
                	} else if("${data.p5}".equals(txt)) {
                		run.setText(StrUtils.addBlank(ct.getData().getP5(), 6), 0);
                	} else if("${data.p6}".equals(txt)) {
                		run.setText(StrUtils.addBlank(ct.getData().getP6(), 6), 0);
                	} else if("${data.p7}".equals(txt)) {
                		run.setText(StrUtils.addBlank(ct.getData().getP7(), 6), 0);
                	} else if("${data.p8}".equals(txt)) {
                		run.setText(StrUtils.addBlank(ct.getData().getP8(), 6), 0);
                	} else if("${data.p9}".equals(txt)) {
                		run.setText(StrUtils.addBlank(ct.getData().getP9(), 6), 0);
                	} else if("${data.p10}".equals(txt)) {
                		run.setText(StrUtils.addBlank(ct.getData().getP10(), 6), 0);
                	} else if("${data.m1}".equals(txt)) {
                		run.setText(StrUtils.addBlank(ct.getData().getM1(), 4), 0);
                	} else if("${data.m1.dx}".equals(txt)) {
                		run.setText(StrUtils.toRmbDx(ct.getData().getM1()), 0);
                	} else if("${data.m2}".equals(txt)) {
                		run.setText(StrUtils.addBlank(ct.getData().getM2(), 6), 0);
                	} else if("${data.m2.dx}".equals(txt)) {
                		run.setText(StrUtils.toRmbDx(ct.getData().getM2()), 0);
                	} else if("${data.m3}".equals(txt)) {
                		run.setText(StrUtils.addBlank(ct.getData().getM3(), 6), 0);
                	} else if("${data.m3.dx}".equals(txt)) {
                		run.setText(StrUtils.toRmbDx(ct.getData().getM3()), 0);
                	} else if("${data.m4}".equals(txt)) {
                		run.setText(StrUtils.addBlank(ct.getData().getM4(), 6), 0);
                	} else if("${data.m4.dx}".equals(txt)) {
                		run.setText(StrUtils.toRmbDx(ct.getData().getM4()), 0);
                	} else if("${data.m5}".equals(txt)) {
                		run.setText(StrUtils.addBlank(ct.getData().getM5(), 6), 0);
                	} else if("${data.m5.dx}".equals(txt)) {
                		run.setText(StrUtils.toRmbDx(ct.getData().getM5()), 0);
                	} else if("${firstPay.dx}".equals(txt)) {
                		run.setText(StrUtils.toRmbDx(ct.getFirstPay()), 0);
                	} else if("${data.m1[1]}".equals(txt)) {	//贯标 服务期限
                		run.setText(ct.getData().getM1() != null && ct.getData().getM1() == 1 ? "■" : "□", 0);
                	} else if("${data.m1[2]}".equals(txt)) {
                		run.setText(ct.getData().getM1() != null && ct.getData().getM1() == 2 ? "■" : "□", 0);
                	} else if("${data.m1[3]}".equals(txt)) {
                		run.setText(ct.getData().getM1() != null && ct.getData().getM1() == 3 ? "■" : "□", 0);
                	} else if("${data.m1[0]}".equals(txt)) {	//双软合同
                		run.setText(ct.getData().getM1() != null && ct.getData().getM1() == 0 ? "■" : "□", 0);
                	} else if("${data.m2[0]}".equals(txt)) {
                		run.setText(ct.getData().getM2() != null && ct.getData().getM2() == 0 ? "■" : "□", 0);
                	} else if("${data.m2[1]}".equals(txt)) {
                		run.setText(ct.getData().getM2() != null && ct.getData().getM2() == 1 ? "■" : "□", 0);
                	} else if("${data.m3[0]}".equals(txt)) {
                		run.setText(ct.getData().getM3() != null && ct.getData().getM3() == 0 ? "■" : "□", 0);
                	} else if("${data.m3[1]}".equals(txt)) {
                		run.setText(ct.getData().getM3() != null && ct.getData().getM3() == 1 ? "■" : "□", 0);
                	} else if("${data.m4[0]}".equals(txt)) {
                		run.setText(ct.getData().getM4() != null && ct.getData().getM4() == 0 ? "■" : "□", 0);
                	} else if("${data.m4[1]}".equals(txt)) {
                		run.setText(ct.getData().getM4() != null && ct.getData().getM4() == 1 ? "■" : "□", 0);
                	/*** 专利 处理 *****************************************************************/
                	} else if("${data.p1[0]}".equals(txt)) {	//贯标 服务期限
                		run.setText("0".equals(ct.getData().getP1()) ? "■" : "□", 0);
                	} else if("${data.p1[1]}".equals(txt)) {
                		run.setText("1".equals(ct.getData().getP1()) ? "■" : "□", 0);
                	} else if("${data.p1[2]}".equals(txt)) {	//贯标 服务期限
                		run.setText("2".equals(ct.getData().getP1()) ? "■" : "□", 0);
                	} else if("${data.p1[3]}".equals(txt)) {
                		run.setText("3".equals(ct.getData().getP1()) ? "■" : "□", 0);
                	} else if("${data.p1[4]}".equals(txt)) {
                		run.setText("4".equals(ct.getData().getP1()) ? "■" : "□", 0);
                	} else if("${yfWtr_pr}".equals(txt)) {
                    	run.setText(ct.getYfWtr(), 0);
                	} else if("${yfTxdz_pr}".equals(txt)) {
                		run.setText(ct.getYfTxdz(), 0);
                	} else if("${yfLxr_pr}".equals(txt)) {
                		run.setText(ct.getYfLxr(), 0);
                	}
                }
            }
            //商标合同
            if("TR".equals(ct.getYwlx())) {
                //添加列表
    			XWPFTable table = doc.getTables().get(0);
    			List<XWPFTableRow> trs = table.getRows();
    			
    			CTFonts fonts = trs.get(2).getCell(0).getParagraphs().get(0).getCTP().getPPr().getRPr().getRFonts();
    			
    			//付款金额
    			XWPFTableCell cell = trs.get(4).getCell(2);
    			XWPFRun run = cell.getParagraphs().get(0).createRun();
    			run.getCTR().addNewRPr().setRFonts(fonts);
    			run.setFontSize(8);
    			run.setText(String.valueOf(ct.getFyhj()));

    			//附加条款，添加到备注
//    			cell = trs.get(5).getCell(0);
//    			run = cell.getParagraphs().get(0).createRun();
//    			run.getCTR().addNewRPr().setRFonts(fonts);
//    			run.setFontSize(8);
//    			if(!StrUtils.isEmpty(ct.getFjtkAdd())) {
//    				run.addBreak();
//    				run.setText(ct.getFjtkAdd());
//    			} 
//    			if(!StrUtils.isEmpty(ct.getFjtkDel())) {
//    				run.addBreak();
//    				run.setText(ct.getFjtkDel());
//    			}

    			List<SbItems> items = ct.getSbItems();
    			int count = (items == null || items.size() < 7) ? 7 : items.size();
    			XWPFTableRow sourceRow = table.getRow(4);
    			for(int i = 0; i < count; i++) {
    				XWPFTableRow row = table.insertNewTableRow(4 + i);
    				row.getCtRow().setTrPr(sourceRow.getCtRow().getTrPr());
    				for(int j = 0; j < 8; j++) {
    					cell = row.addNewTableCell();
    					cell.getCTTc().setTcPr(sourceRow.getCell(0).getCTTc().getTcPr());
    					//金额右对齐
    					if(j == 7) cell.getParagraphs().get(0).setAlignment(ParagraphAlignment.RIGHT);
    					run = cell.getParagraphs().get(0).createRun();
    					run.getCTR().addNewRPr().setRFonts(fonts);
    					run.setFontSize(8);
    					if(j == 0) run.setText(String.valueOf(i + 1));
    					if(items != null && i < items.size()) {
    						if(j == 1) {
    							run.setText(String.valueOf(items.get(i).getXmmc()));
    						} else if(j == 2) {
    							run.setText(String.valueOf(items.get(i).getXmlb()));
    						} else if(j == 3) {
    							run.setText(items.get(i).getSbzw());
    						} else if(j == 4) {
    							run.setText(items.get(i).getSbyw());
    						} else if(j == 5) {
    							run.setText(items.get(i).getSbtx());
    						} else if(j == 6) {
    							run.setText(items.get(i).getSbzh());
    						} else if(j == 7) {
    							run.setText(String.valueOf(items.get(i).getFy()));
    						}
    					} else {
    						run.setText(" ");
    					}
    				}
    			}
    		//版权
            } else if("CR".equals(ct.getYwlx())) {
            	//添加列表
    			XWPFTable table = doc.getTables().get(0);
    			List<XWPFTableRow> trs = table.getRows();
    			
    			CTFonts fonts = trs.get(2).getCell(0).getParagraphs().get(0).getCTP().getPPr().getRPr().getRFonts();
   
    			List<SbItems> items = ct.getSbItems();
    			int count = (items == null || items.size() < 7) ? 7 : items.size();
    			XWPFTableRow sourceRow = table.getRow(4);
    			for(int i = 0; i < count; i++) {
    				XWPFTableRow row = table.insertNewTableRow(3 + i);
    				for(int j = 0; j < 6; j++) {
    					XWPFTableCell cell = row.addNewTableCell();
    					//金额右对齐
    					if(j == 3) cell.getParagraphs().get(0).setAlignment(ParagraphAlignment.RIGHT);
    					XWPFRun run = cell.getParagraphs().get(0).createRun();
    					run.getCTR().addNewRPr().setRFonts(fonts);
    					run.setFontSize(8);
    					if(j == 0) run.setText(String.valueOf(i + 1));
    					if(items != null && i < items.size()) {
    						if(j == 1) {
    							run.setText(String.valueOf(items.get(i).getWtxmmc()));
    						} else if(j == 2) {
    							run.setText(String.valueOf(items.get(i).getZpmc()));
    						} else if(j == 3) {
    							run.setText(String.valueOf(items.get(i).getJs()));
    						} else if(j == 4) {
    							run.setText(String.valueOf(items.get(i).getFy()));
    						} else if(j == 5) {
    							run.setText(items.get(i).getMemo());
    						} 
    					} else {
    						run.setText(" ");
    					}
    				}
    			}
    		//专利
            } else if("PR".equals(ct.getYwlx())) {
            	//添加列表
    			XWPFTable table = doc.getTables().get(0);
    			List<XWPFTableRow> trs = table.getRows();
    			
    			//处理代缴官费服务费
    			XWPFTableCell memoCell = trs.get(3).getCell(1);
    			List<XWPFParagraph> ps = memoCell.getParagraphs();
				for (XWPFParagraph p : ps) {
					for (XWPFRun run : p.getRuns()) {
						String rt = run.getText(0);
	                	if(rt == null) continue;
	                	//${xxxx} 可能在多个run中，这里进行合并
	                	if(rt.trim().startsWith("${")) {
	                		placeholder = true;
	                		txt = rt.trim();
	                		run.setText("", 0);
	                	} else if(placeholder == true) {
	                		txt += rt.trim();
	                		run.setText("", 0);
	                	}
	                	if(placeholder == true && rt.trim().endsWith("}")) {
	                		placeholder = false;
	                	} else {
	                		continue;
	                	}      	
	                	if("${data.m1[1]}".equals(txt)) {
	                		run.setText(ct.getData().getM1() != null && ct.getData().getM1() == 1 ? "■" : "□", 0);
	                	} else if("${data.m1[0]}".equals(txt)) {
	                		run.setText(ct.getData().getM1() != null && ct.getData().getM1() == 0 ? "■" : "□", 0);
	                	} else if("${data.m2}".equals(txt)) {
	                		run.setText(StrUtils.addBlank(ct.getData().getM2(), 6), 0);
	                	} else if("${data.m3}".equals(txt)) {
	                		run.setText(StrUtils.addBlank(ct.getData().getM3(), 6), 0);
	                	} else if("${data.m4}".equals(txt)) {
	                		run.setText(StrUtils.addBlank(ct.getData().getM4(), 6), 0);
	                	}
					}
				}
    			
    			CTFonts fonts = trs.get(2).getCell(0).getParagraphs().get(0).getCTP().getPPr().getRPr().getRFonts();
   
    			List<SbItems> items = ct.getSbItems();
    			int count = (items == null || items.size() < 7) ? 7 : items.size();
    			XWPFTableRow sourceRow = table.getRow(4);
    			for(int i = 0; i < count; i++) {
    				XWPFTableRow row = table.insertNewTableRow(3 + i);
    				for(int j = 0; j < 5; j++) {
    					XWPFTableCell cell = row.addNewTableCell();
    					//金额右对齐
    					if(j == 2 || j == 3 || j == 4) 
    						cell.getParagraphs().get(0).setAlignment(ParagraphAlignment.RIGHT);
    					
    					XWPFRun run = cell.getParagraphs().get(0).createRun();
    					run.getCTR().addNewRPr().setRFonts(fonts);
    					run.setFontSize(8);
    					if(j == 0) run.setText(String.valueOf(i + 1));
    					if(items != null && i < items.size()) {
    						if(j == 1) {
    							run.setText(String.valueOf(items.get(i).getXmmc()));
    						} else if(j == 2) {
    							run.setText(String.valueOf(items.get(i).getXmlb()));
    						} else if(j == 3) {
    							run.setText(String.valueOf(items.get(i).getSbzw()));
    						} else if(j == 4) {
    							run.setText(String.valueOf(items.get(i).getFy()));
    						} 
    					} else {
    						run.setText(" ");
    					}
    				}
    			}
    		//上海 双软合同
            } else if("DS".equals(ct.getYwlx()) && "A".equals(ct.getArea())) {
            	XWPFTable table = doc.getTables().get(0);
    			List<XWPFTableRow> trs = table.getRows();
    			System.out.println("getRows:  " + trs.size());
    			List<SbItems> items = ct.getSbItems();
    			for(int i = 2; i < trs.size(); i++) {
    				//件数
    				XWPFTableCell c2 = trs.get(i).getCell(2);
    				if(c2 == null) continue;
    				//c2.getParagraphs().get(0).setAlignment(ParagraphAlignment.RIGHT);
    				XWPFRun run = c2.getParagraphs().get(0).createRun();
    				if(items  == null || items.get(i - 2) == null) {
    					run.setText("    ");
    				} else {
    					run.setText(String.valueOf(items.get(i - 2).getXmlb()));
    				}
    				
    				//代理服务费（单价）
    				XWPFTableCell c3 = trs.get(i).getCell(3);
    				///c3.getParagraphs().get(0).setAlignment(ParagraphAlignment.RIGHT);
    				run = c3.getParagraphs().get(0).createRun();
    				if(items  == null || items.get(i - 2) == null) {
    					run.setText("    ");
    				} else {
    					run.setText(String.valueOf(items.get(i - 2).getSbzw()));
    				}
    				
    				//代理服务费（共计）
    				XWPFTableCell c4 = trs.get(i).getCell(4);
    				//c4.getParagraphs().get(0).setAlignment(ParagraphAlignment.RIGHT);
    				run = c4.getParagraphs().get(0).createRun();
    				if(items  == null || items.get(i - 2) == null) {
    					run.setText("    ");
    				} else {
    					run.setText(String.valueOf(items.get(i - 2).getFy()));
    				}
    				
    			}
            }
            doc.write(os);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return filename;
	}
	
	/**
	 * 创建双软默认数据
	 * @return
	 */
	public List<SbItems> createDsItems() {
		List<SbItems> list = new ArrayList<>();
		SbItems item = new SbItems();
		item.setXmmc("软件测试");
		list.add(item);
		item = new SbItems();
		item.setXmmc("软件企业认定");
		list.add(item);
		item = new SbItems();
		item.setXmmc("软件产品登记");
		list.add(item);
		item = new SbItems();
		item.setXmmc("软件测试加急");
		list.add(item);
		item = new SbItems();
		item.setXmmc("软件产品认定更名");
		list.add(item);
		return list;
	}
}
